import pandas as pd
import matplotlib.pyplot as plt
from sklearn import preprocessing
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.metrics import accuracy_score

# 读取数据
file = '003/item4/wine-clean.data'
names = ['label', 'a1', 'a2', 'a3', 'a4', 'a5', 'a6', 'a7', 'a8', 'a9', 'a10', 'a11', 'a12', 'a13']
dataset = pd.read_csv(file, names=names)

data = dataset.iloc[:, 1:14]
target = dataset.iloc[:, 0]

print(f'特征数组形状：{data.shape}')
print(f'标签数组形状：{target.shape}')

# 标准化a
scaler = preprocessing.StandardScaler()
cdata = scaler.fit_transform(data)

# 划分训练测试集
x_train, x_test, y_train, y_test = train_test_split(cdata, target, test_size=0.3, random_state=0)

# 寻找最优
k_range = range(1, 21)
cv_scores = []

for k in k_range:
    model = KNeighborsClassifier(n_neighbors=k)
    scores = cross_val_score(model, cdata, target, cv=5, scoring='accuracy')
    cv_scores.append(scores.mean())

best_k = k_range[cv_scores.index(max(cv_scores))]
print(f'最优的 k 值：{best_k}')
print(f'对应的平均准确率：{max(cv_scores):.4f}')

# 可视化 k 值变化
plt.figure(figsize=(8, 5))
plt.rcParams['font.sans-serif'] = ['PingFang SC', 'Arial Unicode MS']  # 兼容 macOS
plt.plot(k_range, [1 - s for s in cv_scores], 'ro-', label='误差率')
plt.plot(k_range, cv_scores, 'bo--', label='准确率')
plt.xlabel('k 的取值')
plt.ylabel('得分')
plt.title('不同 k 值下的模型表现')
plt.legend()
plt.show()

# 使用最优 k 训练模型并预测
model = KNeighborsClassifier(n_neighbors=best_k)
model.fit(x_train, y_train)
pred = model.predict(x_test)

# 评估结果
print(f'测试集预测标签：{pred}')
print(f'测试集真实标签：{y_test.values}')
ac = accuracy_score(y_test, pred)
print(f'模型预测准确率：{ac:.4f}')